package com.avp;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashSet;
import java.io.InputStreamReader;
import java.net.*;
import java.io.*;
import java.util.concurrent.Semaphore;
import java.util.LinkedList;
import java.util.ArrayList;

import android.os.Handler;
import android.widget.ArrayAdapter;

public class DirectoryClient {
	public static int DEFAULTPORT = 9990;
	static Socket _socket = new Socket();
	static BufferedReader _input = null;
	static PrintWriter _output = null;
	public static ArrayList<String> _userList = new ArrayList<String>();
	static Semaphore _getIPFlag = new Semaphore(0);
	static LinkedList<String> _ipQueue = new LinkedList<String>();
	//static Semaphore _fixIt = new Semaphore(0);
	public static Handler adapter = null;

	
	public static boolean connect(String remoteHost, int port, String userName) {
		try {
			_socket.connect(new InetSocketAddress(remoteHost, port));
			_input = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
			_output = new PrintWriter(_socket.getOutputStream());
			login(userName);
			Thread t = new FunctionThread();
			t.start();
			return true;
		}
		catch(Exception e) {
			//Not important at this point
			System.err.println("Problem connection");
			return false;
		}
	}
	public static void disconnect() {
		try {
			_output.println("quit");
			_output.flush();
			_socket.close();
			_socket = new Socket();
		}
		catch(Exception e) {
		}
	}
	public static void pollUsers() {
		//String[] userList = null;
		_output.println("list");
		_output.flush();
		//return userList;
	}
	public static String[] getUsers() {
		return (String[])(_userList.toArray(new String[_userList.size()]));
	}
	//Rules for username: No whitespace
	public static void login(String user) {
		_output.printf("login %s\r\n", user);
		_output.flush();
	}
	//Username to logout not needed as user is tracked by the server
	public static void logout() {
		_output.println("logout");
		_output.flush();
	}
	//Request IP information for a user
	//included just in case, but it's never used
	public static String getIP(String username) {
		_output.println("getip "+username);
		_output.flush();
		//Ensure the listening thread has gotten an IP
		try {
			_getIPFlag.acquire();
		}
		catch(Exception e) {
			//Don't care if thread is interrupted
		}
		return _ipQueue.poll();
		/*
		try{
			if(_input.ready()) {
				String inputLine = _input.readLine();
				if(inputLine.startsWith("2:")) {
					return inputLine.substring(2);
				}
				else if(inputLine.equals("ping")) {
					_output.println("pong");
					_output.flush();
				}
			}
		}
		catch(Exception e){
			//nothing to do here
		}*/
	}
	private static class FunctionThread extends Thread {
		 public void run() {
			while(true) {
				try {
					if(_input.ready()) {
						String inputLine = _input.readLine();
						if(inputLine!=null) {
							if(((inputLine).startsWith("1:"))) {
								//This is a full user list, empty the stored user list
								//and refill it with the supplied list
								_userList.clear();
								String users[] = inputLine.substring(2).split("\\s+");
								for(String s : users) {
									_userList.add(s);
								}
								//_fixIt.release();
								if(adapter != null){
									adapter.sendEmptyMessage(1);
								}
								
							}
							else if(inputLine.startsWith("2:")) {
								//This is a user's IP+host
								String ip = inputLine.substring(2);
								_ipQueue.add(ip);
								_getIPFlag.release();
							}
							else if(inputLine.startsWith("3:")) {
								//Single user sign in
								_userList.add(inputLine.substring(2));
								if(adapter != null){
									adapter.sendEmptyMessage(1);
								}
							}
							else if(inputLine.startsWith("4:")) {
								//Single user log off
								_userList.remove(inputLine.substring(2));
								if(adapter != null){
									adapter.sendEmptyMessage(1);
								}
							}
						}
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	//Respond to pings.  Not used
	private class PingThread extends Thread {
		public void run() {
			while(true) {
				try {
					if(_input.ready()) {
						_input.mark(10);
						char inArray[] = new char[4];
						_input.read(inArray, 0, 4);
						String s = inArray.toString();
						if(s.startsWith("ping")) {
							_output.println("pong");
							_output.flush();
						}
						else {
							_input.reset();
						}
					}
				}
				catch(IOException ioEx) {

				}
			}
		}
	}
}
